#!/usr/bin/perl 
BEGIN{
	push (@INC, "./libs/");
}

use strict;
use CGI;

my $expiry = "+15m";
my $path = "/cgi-bin/paaac/";
my $cookie_name = "test";
my $script_name = "main.cgi";
my $uid;

page();

# Present a login screen
sub login {
		my $q = shift;
		print $q->header();
		print $q->start_html();
		print  '<form method="post" action="'.$path.$script_name.'" enctype="multipart/form-data">
		user: <input type="text" name="user"><br>
		pass: <input type="password" name="pass"><br>
		<input type="submit" value="login">
		</form>';
		print $q->end_html();
} 

# The main content for valid users
sub content {
	my $q = shift;
	my $id_string = $q->cookie($cookie_name);
	my $ip = $ENV{'REMOTE_ADDR'};
	if($uid){
		print "Logged in as $uid.<br>\n";
	} else {
		print "Not logged in.<br>\n";
	}
	my $action = $q->param("do");
	if(!defined($action)) {
		print "What would you like to do?<br>";
		print  '<form method="post" action="'.$path.$script_name.'" enctype="multipart/form-data">';
		print '<input type="radio" name="do" value="logout" checked> ';
		print "logout <br>";
		print '<input type="radio" name="do" value="perms"> ';
		print "check your permissions <br>";
		print '<input type="submit">';
		print "</form>";
		print $q->end_html();
	} else {
		if($action eq "logout") {
			do_stuff(sub {return(@_)}, "logout", $id_string, $ip);
		} elsif ($action eq "file") {
			my $fn = $q->param("filename");
			do_stuff(sub {print(@_)}, "file", $id_string, $fn, $ip);
		} elsif ($action eq "perms"){
			my %perms = all_perms($id_string, $ip);
			foreach my $p (keys %perms){
				if($perms{$p}){
					print("$uid has $p access<br>\n");
				}
			}	
		}
		print "<br>\n";
		print "<a href=".$path.$script_name.">Back</a>\n";	
	}
}

####################################################################

# Support functions
sub all_perms{
	my @perms = ("admin", "del", "mod", "add", "view");
	my %user_perm;
	my $cookie = shift;
	my $ip = shift;
	foreach my $p (@perms){		
		if(check_user_perm($cookie, $p, $ip) eq "OK"){
			$user_perm{$p} = 1;
		} else {
			$user_perm{$p} = 0;
		}
	}
	return %user_perm;
}

sub check_user_perm{
	my $cookie = shift;
	my $object = shift;
	my $ip = shift;
	my $ret = do_stuff(sub {return "@_"}, "perm", $cookie, $object, $ip);
	return $ret;
}

sub page {
	my $query = CGI->new();
	$uid = $query->param("user");
	my $pass = $query->param("pass");
	my $id_string = $query->cookie($cookie_name);
	$id_string =~ s/\%([A-Fa-f0-9]{2})/pack('C', hex($1))/seg; # url decode
	my $ip = $ENV{'REMOTE_ADDR'};

	# Make sure the user is logged in.
	if(!($uid && $pass)) {
		# not logging in
		if(!$id_string) {
			# no cookie
				login($query);
			} else {
			# cookie
			do_stuff(sub {
				my $reply = shift;
				if(!defined($reply)) {
					# invalid
					login($query);
				} else {
					# valid
					my $action = $query->param("do");
					my $cookie;
					if($action eq "logout"){
						$cookie = 
						$query->cookie(	-name	=> $cookie_name,
								-value	=> "logout",
								-expires=> "-1d");
					}else{
						$cookie = 
						$query->cookie(	-name	=> $cookie_name,
								-value	=> $id_string,
								-expires=> $expiry);
						$uid = $reply;
					}
					print $query->header(-cookie => $cookie);
					print $query->start_html();
					#print "<pre>".$id_string."</pre>";
					content($query);
					print $query->end_html();
				}
				}, "cookie", $id_string, $ip);
		}

	} else {
		# log in with a password
		do_stuff(sub {
			$id_string = shift;
			if(!defined($id_string)) {
				# invalid 
				login($query);
			} else {
				# valid
				my $cookie = $query->cookie(	-name 	=> $cookie_name,
								-value	=> $id_string,
								-expires=> $expiry);
				print $query->header(-cookie => $cookie);
				print $query->start_html();
				#print "<pre>".$id_string."</pre>";
				content($query);
			}
		}, "passwd", $uid, $pass, $ip);
			print $query->end_html();
	}

}

sub do_stuff {
	my $kont = shift;
	my @args = @_;
	# fork!	
	my $fd = open(FD, "-|");
	die "Can't open pipe." unless defined($fd);
	if($fd == 0) {
		# child process execs the suid wrapper
		exec "./suid_core.pl", @args;
	}else{
		# meanwhile the parent catches the output
		my $reply = <FD>;
		close FD;
		&${kont}($reply);
	}
}



return 1;

